package encrypt

import (
	"bytes"
	"crypto/cipher"
	"crypto/des"
	"crypto/md5"
	"crypto/sha256"
	"encoding/hex"
	"strings"
)

const (
	/** MD5加密，不可还原 */
	MD5 = "MD5"
	/** SHA加密，不可还原 */
	SHA = "SHA"
	/** DES加密，可以还原 */
	DES = "DES"
	// DES加密密钥，解密时也要用到 该变量不可以改变，否则将无法对密码进行解密
	//                   "theta ne"
	PASSWORD_CRYPT_KEY = "tomiscat"
)

var EncryptUtil = &encryptUtil{}

type encryptUtil struct {
}

func (u encryptUtil) Encrypt(orgStr string, encType string) string {
	if strings.ToLower(encType) == "md5" {
		m := md5.New()
		m.Write([]byte(orgStr))
		return hex.EncodeToString(m.Sum(nil))
	} else if strings.ToLower(encType) == "sha" {
		m := sha256.New()
		m.Write([]byte(orgStr))
		return hex.EncodeToString(m.Sum(nil))
	} else if strings.ToLower(encType) == "des" {
		return string(encryptDES([]byte(orgStr), []byte(PASSWORD_CRYPT_KEY)))
	}
	return ""
}
func padding(src []byte, blocksize int) []byte {
	n := len(src)
	padnum := blocksize - n%blocksize
	pad := bytes.Repeat([]byte{byte(padnum)}, padnum)
	dst := append(src, pad...)
	return dst
}

func unpadding(src []byte) []byte {
	n := len(src)
	unpadnum := int(src[n-1])
	dst := src[:n-unpadnum]
	return dst
}

func encryptDES(src []byte, key []byte) []byte {
	block, _ := des.NewCipher(key)
	src = padding(src, block.BlockSize())
	blockmode := cipher.NewCBCEncrypter(block, key)
	blockmode.CryptBlocks(src, src)
	return src
}

func decryptDES(src []byte, key []byte) []byte {
	block, _ := des.NewCipher(key)
	blockmode := cipher.NewCBCDecrypter(block, key)
	blockmode.CryptBlocks(src, src)
	src = unpadding(src)
	return src
}
